/*
 * @Description: 城市列表
 * @Author: Yong
 * @Date: 2021-09-23 10:34:45
 * @LastEditTime: 2021-09-25 15:24:33
 */
import React from "react"
import { Toast } from 'antd-mobile'
// 导入 List 组件
import { List, AutoSizer } from 'react-virtualized'
import './index.scss'
import { getCityList, getHotCity } from '../../apis/city'
import { getCurrentCity } from '../../utils/map-function'
import NavHeader from "../../components/NavHeader"

// 格式化城市列表数据
const formatCityData = list => {
    const cityList = {} // { a: [{}, {}] }

    list.forEach(item => {
        const firstWord = item.short.substring(0, 1)
        if (cityList[firstWord]) {
            cityList[firstWord].push(item)
        } else {
            cityList[firstWord] = [item]
        }
    })

    // 获取字母索引
    const cityIndex = Object.keys(cityList).sort()

    return {
        cityList,
        cityIndex
    }
}
// 封装处理字母索引的方法
const formatCityIndex = letter => {
    switch (letter) {
        case '#':
            return '当前定位'
        case 'hot':
            return '热门城市'
        default:
            return letter.toUpperCase()
    }
}
// 索引（A、B等）的高度
const TITLE_HEIGHT = 36
// 每个城市名称的高度
const NAME_HEIGHT = 50
// 有房源的城市
const HOUSE_CITY = ['北京', '上海', '广州', '深圳']

export default class CityList extends React.Component {
    constructor() {
        super()
        this.state = {
            cityList: {},
            cityIndex: [],
            activeIndex: 0,
        }
        this.cityListComponent = React.createRef()
    }

    async componentDidMount () {
        await this.GetCityList()

        // 调用 measureAllRows，提前计算 List 中每一行的高度，实现 scrollToRow 的精确跳转
        this.cityListComponent.current.measureAllRows()
    }

    // 获取页面城市列表信息
    async GetCityList () {
        // 获取城市列表
        const List = await getCityList()
        const { cityList, cityIndex } = formatCityData(List)

        // 获取热门城市数据
        const HotCity = await getHotCity()
        cityList['hot'] = HotCity
        cityIndex.unshift('hot')

        // 获取当前定位城市
        const curCity = await getCurrentCity()
        cityList['#'] = [curCity]
        cityIndex.unshift('#')

        this.setState({ cityList, cityIndex })
    }

    // 动态获取每一行得高度
    getRowHeight = ({ index }) => {
        // 索引标题高度 + 城市数量 * 城市名称的高度
        const { cityList, cityIndex } = this.state
        return TITLE_HEIGHT + cityList[cityIndex[index]].length * NAME_HEIGHT
    }

    // List组件渲染每一行的方法：
    rowRenderer = ({
        key,            // Unique key within array of rows
        index,          // 索引号
        isScrolling,    // 当前项是否正在滚动中
        isVisible,      // 当前项在 List 中是可见的
        style           // 注意：重点属性，一定要给每一个行数据添加该样式！作用：指定每一行的位置
    }) => {
        // 获取每一行的字母索引
        const { cityIndex, cityList } = this.state
        const letter = cityIndex[index]
        return (
            <div key={key} style={style} className="city">
                <div className="title">{formatCityIndex(letter)}</div>
                {cityList[letter].map(item => (
                    <div
                        className="name"
                        key={item.value}
                        onClick={() => this.changeCity(item)}
                    >
                        {item.label}
                    </div>
                ))}
            </div>
        )
    }

    // 改变当前城市
    changeCity ({ label, value }) {
        if (HOUSE_CITY.indexOf(label) > -1) {
            localStorage.setItem('hkzf_city', JSON.stringify({ label, value }))
            this.props.history.go(-1)
        } else {
            Toast.info('该城市暂无房源数据', 1, null, false)
        }
    }

    // 用于获取List组件中渲染行的信息
    onRowsRendered = ({ startIndex }) => {
        // 只有索引不一致才执行
        if (this.state.activeIndex !== startIndex) {
            this.setState({
                activeIndex: startIndex
            })
        }
    }

    // 封装渲染右侧索引列表的方法
    renderCityIndex () {
        // 获取到 cityIndex，并遍历其，实现渲染
        const { cityIndex, activeIndex } = this.state
        return cityIndex.map((item, index) => (
            <li
                className="city-index-item"
                key={item}
                onClick={() => {
                    // 获取List组件实例 - 跳转至对应索引
                    this.cityListComponent.current.scrollToRow(index)
                }}
            >
                <span className={activeIndex === index ? 'index-active' : ''}>
                    {item === 'hot' ? '热' : item.toUpperCase()}
                </span>
            </li>
        ))
    }

    render () {
        return (
            <div className="cityList">
                {/* 顶部导航 */}
                <NavHeader>城市选择</NavHeader>
                {/* 城市列表 */}
                <AutoSizer>
                    {({ width, height }) => (
                        <List
                            ref={this.cityListComponent}
                            width={width}
                            height={height}
                            rowCount={this.state.cityIndex.length}
                            rowHeight={this.getRowHeight}
                            rowRenderer={this.rowRenderer}
                            onRowsRendered={this.onRowsRendered}
                            scrollToAlignment="start"
                        />
                    )}
                </AutoSizer>
                {/* 右侧索引列表 */}
                <ul className="city-index">{this.renderCityIndex()}</ul>
            </div>
        )
    }
}